<!--
 * @Descripttion: 
 * @version: 
 * @Author: Jsonco
 * @Date: 2022-12-18 19:48:04
 * @LastEditors: sueRimn
 * @LastEditTime: 2023-08-29 20:57:17
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <title>WebGL Shader实战3</title>
    <script src="../lib/gl-utils.js"></script>
    <script src="../lib/gl-debug.js"></script>
    <script src="../lib/ice-utils.js"></script>
    <script src="../lib/gl-matrix.js"></script>
    <!-- <script src="../../lib/gl-lint.js" crossorigin></script> -->
    <script type="text/javascript">

        var gl = null;
        var angle = 45;
        var canvas = null;
        var startTime = new Date().getTime();
        var array;
        var audioContext;
        var analyser;
        async function main() {
            startTime = new Date().getTime();
            initWebgl();
            initShader();
        }

        function render() {
            window.requestAnimationFrame(() => {
                analyser.getByteFrequencyData(array);
                console.log(array[0]);
                let v = document.getElementById('input_u_roundness').value;
                let u_Roundness = gl.getUniformLocation(gl.program, 'u_roundness');
                gl.uniform1f(u_Roundness, array[0] / 100);
                draw()
                window.requestAnimationFrame(render)
            })
        }

        function initWebgl() {
            // 获取canvas对象
            canvas = document.getElementById('gl');
            //获取webgl绘制对象
            gl = getWebGLContext(canvas);
            gl.getExtension('OES_standard_derivatives');
            gl.viewport(0, 0, canvas.clientWidth, canvas.clientHeight);
            if (!gl) {
                console.log('不支持webgl哦！');
                return;
            }
        };
        async function initShader() {
            // 初始化主色器程序
            let FSHADER_SOURCE = await loadShaderFromFile("./shader/shader.frag.glsl")
            let VSHADER_SOURCE = await loadShaderFromFile("./shader/shader.vert.glsl")
            if (VSHADER_SOURCE && FSHADER_SOURCE) {
                initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE);

                initBuffer();
                initEvent();

            }
        }
        var positions = [];
        var indices = [];
        var normals = [];
        function initBuffer() {

            var SPHERE_DIV = 16;

            var i, ai, si, ci;
            var j, aj, sj, cj;
            var p1, p2;


            // Generate coordinates
            for (j = 0; j <= SPHERE_DIV; j++) {
                aj = j * Math.PI / SPHERE_DIV;
                sj = Math.sin(aj);
                cj = Math.cos(aj);
                for (i = 0; i <= SPHERE_DIV; i++) {
                    ai = i * 2 * Math.PI / SPHERE_DIV;
                    si = Math.sin(ai);
                    ci = Math.cos(ai);

                    positions.push(si * sj);  // X
                    positions.push(cj);       // Y
                    positions.push(ci * sj);  // Z


                    normals.push(si * sj, cj, ci * sj);
                }
            }
            // console.log("positions",positions);
            // Generate indices
            for (j = 0; j < SPHERE_DIV; j++) {
                for (i = 0; i < SPHERE_DIV; i++) {
                    p1 = j * (SPHERE_DIV + 1) + i;
                    p2 = p1 + (SPHERE_DIV + 1);

                    indices.push(p1);
                    indices.push(p2);
                    indices.push(p1 + 1);

                    indices.push(p1 + 1);
                    indices.push(p2);
                    indices.push(p2 + 1);
                }
            }

            let pointPosition = new Float32Array(positions);
            let aPsotion = gl.getAttribLocation(gl.program, "a_position");
            let triangleBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, pointPosition, gl.STATIC_DRAW);
            gl.enableVertexAttribArray(aPsotion);
            gl.vertexAttribPointer(aPsotion, 3, gl.FLOAT, false, 0, 0);

            let aNormal = gl.getAttribLocation(gl.program, "a_Normal");
            let normalsBuffer = gl.createBuffer();
            let normalsArr = new Float32Array(normals);
            gl.bindBuffer(gl.ARRAY_BUFFER, normalsBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, normalsArr, gl.STATIC_DRAW);
            gl.enableVertexAttribArray(aNormal);
            gl.vertexAttribPointer(aNormal, 3, gl.FLOAT, false, 0, 0);

            let u_DiffuseLight = gl.getUniformLocation(gl.program, 'u_DiffuseLight');
            gl.uniform3f(u_DiffuseLight, 1.0, 1.0, 1.0);
            let u_LightDirection = gl.getUniformLocation(gl.program, 'u_PointLightPosition');
            gl.uniform3fv(u_LightDirection, [3.0, 3.0, 4.0]);
            let u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
            gl.uniform3f(u_AmbientLight, 0.2, 0., 0.2);

            let u_Eyedirection = gl.getUniformLocation(gl.program, 'u_eyedirection');
            gl.uniform3fv(u_Eyedirection, [0, 0, 2]);



            let indexBuffer = gl.createBuffer();
            let indices1 = new Uint8Array(indices);
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices1, gl.STATIC_DRAW);





            //矩阵变换
            let ProjMatrix = glMatrix.mat4.create();
            glMatrix.mat4.identity(ProjMatrix);
            //角度小，看到的物体大，角度大，看到的物体小。
            glMatrix.mat4.perspective(ProjMatrix, angle * Math.PI / 180, canvas.clientWidth / canvas.clientHeight, 1, 1000)    //修改可视域范围

            let uniformMatrix1 = gl.getUniformLocation(gl.program, "u_formMatrix");

            let ModelMatrix = glMatrix.mat4.create();
            glMatrix.mat4.identity(ModelMatrix);
            glMatrix.mat4.translate(ModelMatrix, ModelMatrix, [0, 0, 0]);

            let ViewMatrix = glMatrix.mat4.create();
            glMatrix.mat4.identity(ViewMatrix);
            glMatrix.mat4.lookAt(ViewMatrix, [3, 3, 3], [0, 0, 0], [0, 1, 0]);

            let mvMatrix = glMatrix.mat4.create();
            glMatrix.mat4.identity(mvMatrix);
            glMatrix.mat4.multiply(mvMatrix, ViewMatrix, ModelMatrix);

            let mvpMatrix = glMatrix.mat4.create();
            glMatrix.mat4.identity(mvpMatrix);
            glMatrix.mat4.multiply(mvpMatrix, ProjMatrix, mvMatrix);
            gl.uniformMatrix4fv(uniformMatrix1, false, mvpMatrix)



        }
        function draw() {

            let time = (new Date().getTime() - startTime) * 0.001;
            let u_Time = gl.getUniformLocation(gl.program, 'u_time');
            gl.uniform1f(u_Time, time);

            let u_Resolution = gl.getUniformLocation(gl.program, 'u_Resolution');
            let resolution = glMatrix.vec2.create();
            resolution[0] = 512.0;
            resolution[1] = 512.0;
            gl.uniform2fv(u_Resolution, resolution);

            gl.clearColor(0, 0, 0, 1);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
            gl.enable(gl.DEPTH_TEST);



            gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);

            gl.flush();
        }

        function mouseMove(e) {
            let mx = e.offsetX / 512.;
            let my = e.offsetY / 512.;
            mousePosition = [mx, my];
            let u_Mouse = gl.getUniformLocation(gl.program, 'u_Mouse');
            gl.uniform2fv(u_Mouse, mousePosition);

        }
        function initEvent() {
            // canvas.addEventListener('mousemove', mouseMove, true);
            inputchange1()
            inputchange2()
            inputchange3()
            inputchange4()

        }
        function inputchange1(params) {
            let v = document.getElementById('input_u_roundness').value;
            let u_Roundness = gl.getUniformLocation(gl.program, 'u_roundness');
            gl.uniform1f(u_Roundness, v);
        }

        function inputchange2(params) {
            let v = document.getElementById('input_u_GradientMix').value;
            let u_GradientMix = gl.getUniformLocation(gl.program, 'u_GradientMix');
            gl.uniform1f(u_GradientMix, v);
        }
        function inputchange3(params) {
            let v = document.getElementById('input_u_Saturation').value;
            let u_Saturation = gl.getUniformLocation(gl.program, 'u_Saturation');
            gl.uniform1f(u_Saturation, v);
        }
        function inputchange4(params) {
            let v = document.getElementById('input_u_Brightness').value;
            let u_Brightness = gl.getUniformLocation(gl.program, 'u_Brightness');
            gl.uniform1f(u_Brightness, v);
        }


        function changefile(params) {
            try {
                audioContext = new window.AudioContext();

            } catch (e) {
                Console.log('浏览器不支持音频');
            }
            audioContext.resume().then(() => {

                let audioInput = document.getElementById('uploadedFile');
                let filedata = audioInput.files[0];
                let fr = new FileReader(); //实例化一个FileReader用于读取文件
                fr.readAsArrayBuffer(filedata);//发起异步请求
                fr.onload = function (e) {
                    var fileResult = e.target.result;
                    audioContext.decodeAudioData(fileResult, function (buffer) {
                        var audioBufferSouceNode = audioContext.createBufferSource();

                        audioBufferSouceNode.buffer = buffer;
                        analyser = audioContext.createAnalyser();
                        audioBufferSouceNode.connect(analyser);
                        analyser.connect(audioContext.destination);
                        audioBufferSouceNode.start(0);
                        analyser.fftSize = 2048;
                        array = new Uint8Array(1);
                        analyser.getByteFrequencyData(array);
                        render()

                    }, function (e) { //这个是解码失败会调用的函数
                        console.log("!哎玛，文件解码失败:(");
                    });
                };

            })


        }
    </script>
</head>

<body onload="main()">
    <canvas id="gl" width="512" height="512">
    </canvas>
    <br> 外形： <br>
    <input type="range" id="input_u_roundness" min="0" max="1" step="0.1" onchange='inputchange1()'>
    <br> 扩撒粒度： <br>
    <input type="range" id="input_u_GradientMix" min="0.01" max="10" step="0.1" value="1" onchange='inputchange2()'>
    <br> 颜色深度： <br>
    <input type="range" id="input_u_Saturation" min="0.01" max="1" step="0.1" value="0.5" onchange='inputchange3()'>
    <br> 亮度： <br>
    <input type="range" id="input_u_Brightness" min="0.01" max="1" step="0.1" value="0.4" onchange='inputchange4()'>
    <br> 选择文件 <br>
    <input type="file" id="uploadedFile" onchange="changefile(this)"></input>
</body>

</html>